package com.tanhua.dubbo.api;

import cn.hutool.core.util.ObjectUtil;
import com.itheima.model.enmus.CommentSubject;
import com.itheima.model.enmus.CommentType;
import com.itheima.model.mongo.Comment;
import com.itheima.model.mongo.Movement;
import com.itheima.model.vo.PageResult;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.List;

@DubboService
public class CommentApiImpl implements CommentApi{
    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 发布评论，并提取评论数量
     * @param comment
     * @return
     */
    @Override
    public Integer commit(Comment comment) {
        //查询动态
        Movement movement = mongoTemplate.findById(comment.getPublishId(), Movement.class);
        //2、向comment对象设置被评论人属性
        if (movement != null) {
            comment.setPublishUserId(movement.getUserId());
        }

        //3、保存到数据库
        mongoTemplate.save(comment);

        //4、更新动态表中的对应字段
        Query query = Query.query(Criteria.where("id").is(comment.getPublishId()));
        Update update =new Update();

        if (comment.getCommentType() == CommentType.LIKE.getType()){
                update.inc("likeCount",1);

        }else if (comment.getCommentType() == CommentType.COMMENT.getType()){
            update.inc("commentType",1);
        }else {
            update.inc("loveCount",1);
        }

        //5、设置更新的参数
        FindAndModifyOptions options = new FindAndModifyOptions();
        options.returnNew(true);    //获取更新后的最新数据
        Movement modify = mongoTemplate.findAndModify(query, update, options, Movement.class);
        //5、获取最新评论数量，并返回
        return modify.statisCount(comment.getCommentType());
    }

    //查询出评论数据列表
    @Override
    public List<Comment> findCommendList(String movementId, CommentType commentType, Integer page, Integer pagesize) {
        //1、构造查询条件
        Query query = Query.query(Criteria.where("publishId").is(new ObjectId(movementId)).and("commentType")
                .is(commentType.getType()))
                .skip((page -1) * pagesize)
                .limit(pagesize)
                .with(Sort.by(Sort.Order.desc("created")));
        //2、查询并返回
        return mongoTemplate.find(query,Comment.class);
    }

    //判断comment数据是否存在
    @Override
    public Boolean likeComment(String movementId, Long userId, CommentType commentType) {
        Criteria criteria = Criteria.where("userId").is(userId)
                .and("publishId").is(new ObjectId(movementId))
                .and("commentType").is(commentType.getType());
        Query query = Query.query(criteria);
        //判断数据是否存在
        return mongoTemplate.exists(query,Comment.class);
    }

    //删除取消点赞
    @Override
    public Integer delete(Comment comment) {
        //1、删除Comment表数据
        Criteria criteria = Criteria.where("userId").is(comment.getUserId())
                .and("publish").is(comment.getPublishId())
                .and("commentType").is(comment.getCommentType());
        Query query = Query.query(criteria);
        mongoTemplate.remove(query,Comment.class);
        //2、修改动态表中的总数量
        Query movementQuery = Query.query(Criteria.where("id").is(comment.getPublishId()));
        Update update = new Update();
        if (comment.getCommentType() == CommentType.LIKE.getType()){
            update.inc("likeCount", -1);
        }else if (comment.getCommentType() == CommentType.COMMENT.getType()){
        update.inc("commentCount", -1);

        }else {
            update.inc("loveCount", -1);
        }
        //设置更新参数
        FindAndModifyOptions options = new FindAndModifyOptions();

        //获取更新后的数据
        options.returnNew(true);
        Movement modify = mongoTemplate.findAndModify(movementQuery, update, options, Movement.class);
        //获取最新评论数量，并返回
        return modify.statisCount(comment.getCommentType());
    }

    @Override
    public Integer deleteLikeComment(Comment comment, CommentSubject commentSubject) {
        //删除当前用户的点赞/喜欢数据
        Criteria criteria = Criteria.where("publishId").is(comment.getPublishId())
                .and("commentType").is(comment.getCommentType())
                .and("userId").is(comment.getUserId());
        mongoTemplate.remove(Query.query(criteria), Comment.class);
        //更新动态表对应的点赞/喜欢数据、返回最新结果
        Integer change = -1;
        return getCount(comment, commentSubject, change);
    }

    @Override
    public Boolean hasComment(String movementId, Long userId, CommentType commentType) {
        Criteria criteria = Criteria.where("userId").is(userId)
                .and("publishId").is(new ObjectId(movementId))
                .and("commentType").is(commentType.getType());
        Query query = Query.query(criteria);
        return mongoTemplate.exists(query,Comment.class); //判断数据是否存在
    }

    @Override
    public Integer saveCommentLike(Comment comment, CommentSubject commentSubject) {
        Long publishUserId = null;
        switch (commentSubject) {
            case MOVEMENT: {
                //查询动态信息
                Movement movement = mongoTemplate.findById(comment.getPublishId(), Movement.class);
                if (ObjectUtil.isNotEmpty(movement)) {
                    publishUserId = movement.getUserId();
                }
                break;
            }
            case COMMENT: {
                Comment parentComment = mongoTemplate.findById(comment.getPublishId(), Comment.class);
                if (ObjectUtil.isNotEmpty(parentComment)) {
                    publishUserId = parentComment.getUserId();
                }
                break;
            }
            case VIDEO: {
                /*Video video = mongoTemplate.findById(comment.getPublishId(), Video.class);
                if (ObjectUtil.isNotEmpty(video)) {
                    publishUserId = video.getUserId();
                }*/
                break;
            }
            default:
                break;
        }
        //设置Comment的发布用户id
        comment.setPublishUserId(publishUserId);
        //添加评论数据
        mongoTemplate.save(comment);
        //更新并保存动态数据、返回最新结果
        Integer changeNum = 1;
        return getCount(comment, commentSubject, changeNum);
    }

    /**
     * 抽取公共方法
     * @param comment
     * @param commentSubject
     * @param changeNum
     * @return
     */
    private Integer getCount(Comment comment, CommentSubject commentSubject, Integer changeNum) {
        //更新动态数据的点赞、评论、喜欢对应的字段
        Query query = Query.query(Criteria.where("id").is(comment.getPublishId()));
        Update update = new Update();
        Integer commentType = comment.getCommentType();
        if (commentType.equals(CommentType.LIKE.getType())) {
            update.inc("likeCount", changeNum);
        } else if (commentType.equals(CommentType.COMMENT.getType())) {
            update.inc("commentCount", changeNum);
        } else {
            update.inc("loveCount", changeNum);
        }
        //设置更新参数
        FindAndModifyOptions options = new FindAndModifyOptions();
        options.returnNew(true);    //true--获取更新后的数据
        //获取最新的对应字段数量并返回
        Integer count = null;
        switch (commentSubject) {
            case MOVEMENT: {
                Movement movementModify = mongoTemplate.findAndModify(query, update, options, Movement.class);
                count = movementModify.statisCount(commentType);
                break;
            }
            case COMMENT: {
                Comment commentResult = mongoTemplate.findAndModify(query, update, options, Comment.class);
                count = commentResult.getLikeCount();
                break;
            }
            case VIDEO: {
                /*Video videoResult = mongoTemplate.findAndModify(query, update, options, Video.class);
                count = videoResult.statisCount(comment.getCommentType());*/
                break;
            }
            default:
                break;
        }
        return count;
    }
}
